import 'dart:async';

import 'package:flutter/material.dart';
import 'package:logger/logger.dart';
import 'package:qgchat/common/class/websocket/settings.dart';
import 'package:qgchat/common/global/global.dart';
import 'package:qgchat/http/models/socketModel.dart';
import 'package:web_socket_channel/io.dart';

/// 视频通话中的websocket，用作计费
class VideoWs {
  /// websocket
  IOWebSocketChannel channel;

  /// stearm
  final ValueNotifier<Stream> streamNotifier = ValueNotifier<Stream>(null);

  /// 计时器
  Timer _timer;

  /// 启动socket
  void start(String userToken, int inv) {
    // 关闭旧socket
    if (channel != null) {
      channel.sink.close();
    }

    String connectUrl = '$VIDEO_CONNECT_ADDRESS?token=$userToken&id=$inv';
    channel = IOWebSocketChannel.connect(connectUrl);
    streamNotifier.value = channel.stream.asBroadcastStream();
    streamNotifier.value.listen(_onData, onError: _onError, onDone: _onDone);
    // channel.stream.listen(_onData, onError: _onError, onDone: _onDone);

    Logger().i('连上计费socket');
    // 心动的开始
    _heartbeat();
  }

  /// 监听socket消息
  void _onData(event) {
    SocketModel data = SocketModel.fromJson(deJson(event));
    switch (data.datatype) {
      case 'nomoney': // 提示没钱
        showToast("您的余额不足通话");
        break;
      case 'error': //错误
        showToast(data.msg);
        break;
      default:
    }
  }

  /// 没钱挂断电话回调
  Function listenNoMoney;

  /// 监听socket错误
  void _onError(e) {
    print('socket错误：$e');
  }

  /// 监听socket结束
  void _onDone() {
    Logger().i('计费socket 结束');
    if (listenNoMoney != null) {
      listenNoMoney();
    }
    print('计费socket结束');
  }

  /// 发送消息
  void _send(Map obj) {
    if (channel == null) {
      return;
    }
    channel.sink.add(toJson(obj));
  }

  /// 心跳包
  void _heartbeat() {
    _timer?.cancel();
    _timer = Timer.periodic(VIDEO_HEARTBEAT, (timer) {
      _send({'datatype': 'heartbeat'});
    });
  }

  // ##########  暴露的api (功能区)  ##############

  /// 销毁WebSocket
  void dispose() {
    channel?.sink?.close();
    channel = null;
    _timer?.cancel();
  }
}
